﻿using System;
using System.Text;
using PreeRegisterModel;
using DrSoftsFrame;
using System.Data;
using PreeRegisterDAL;
using Newtonsoft.Json.Linq;
using System.Web;

namespace PreeRegisterBLL
{
    public class OrderBLL
    {
        /// <summary>
        /// 长治和平 预约挂号
        /// </summary>
        /// <param name="xml">请求信息</param>
        /// <returns></returns>
        public static OrderResponseModel Order(OrderParameterModel_Index request)
        {

            string strRef = "";
            string ls_err = "";

            OrderResponseModel model = new OrderResponseModel();
            OrderResponseReturnModel orderResponseReturnModel = new OrderResponseReturnModel();
            OrderModel Result = new OrderModel();
            try
            {
                //预约
                //Result = PreeOrder_CZHP(request, ref ls_err);
                Result = PreeOrder_CZHP_New(request, ref ls_err);
                if (ls_err != "")
                {
                    //{"9999":"1", "9998":"2","9997":"3","9996",:"4"}
                    if (ls_err.Contains("号已挂完"))
                        orderResponseReturnModel.code = "9999";
                    else if (ls_err.Contains("停诊"))
                        orderResponseReturnModel.code = "9998";
                    else if (ls_err.Contains("根据医生编码") && ls_err.Contains("实际返回数量[0]"))
                        orderResponseReturnModel.code = "9997";
                    else if (ls_err.Contains("排班已过期。"))
                        orderResponseReturnModel.code = "9997";
                    else if (ls_err.Contains("获取医生排班信息失败"))
                        orderResponseReturnModel.code = "9997";
                    else if (ls_err.Contains("已经预约"))
                        orderResponseReturnModel.code = "9996";
                    else
                        orderResponseReturnModel.code = "0";

                    orderResponseReturnModel.msg = ls_err;
                    orderResponseReturnModel.result = Result;
                    model.body = orderResponseReturnModel;
                    return model;
                }
                else
                {
                    orderResponseReturnModel.code = "1";
                    orderResponseReturnModel.msg = strRef;
                    orderResponseReturnModel.result = Result;
                }
                model.body = orderResponseReturnModel;
                return model;
            }
            catch (Exception err)
            {
                throw;
            }
        }

        /// <summary>
        /// 长治和平预约【调用医院模式】
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="ls_err">返回信息</param>
        /// <returns></returns>
        static OrderModel PreeOrder_CZHP(OrderParameterModel_Index request, ref string ls_err)
        {
            OrderModel Result = new OrderModel();
            try
            {
                string url_getorder = CommonBLL.GetConfig("CZHP_ADDR") + "MakeOutPatientAppointment?parameters=";
                StringBuilder head = new StringBuilder();
                StringBuilder body = new StringBuilder();
                /*
                 body.Append(" {");
                 body.Append("\"AppointmentCode\": \"20170508004001350006\",");
                 body.Append("\"Patient\": {");
                     body.Append("\"PatientId\": \"5897d0f30cf22b856006ef3e\",");
                    body.Append("\"PatientName\": \"靳淑芳\",");
                     body.Append("\"IdentityCard\": \"140581199303166225\",");
                     body.Append("\"Birthday\": \"1993-03-16\",");
                     body.Append("\"Gender\": \"女\",");
                     body.Append("\"Age\": \"24\",");
                     body.Append("\"Telephone\": \"18835641413\",");
                     body.Append("\"Address\": \"\",");
                     body.Append("\"PatientCode\": \"\",");
                     body.Append("\"PatientCardCode\": \"\",");
                     body.Append("\"AgeUnit\": \"岁\"");
                 body.Append("},");
                 body.Append("\"AppointmentSource\": \"近医通微信\"");
                 body.Append("}");
                 */

                head.Append("{head:\"\"");
                body.Append(" {");
                body.AppendFormat("\"AppointmentCode\":\"{0}\",", request.iid);
                body.Append("\"Patient\": {");
                body.AppendFormat("\"PatientId\": \"{0}\",", request.card);
                body.AppendFormat("\"PatientName\": \"{0}\",", request.name);
                body.AppendFormat("\"IdentityCard\": \"{0}\",", request.card);
                body.AppendFormat("\"Birthday\": \"{0}\",", request.birth);
                body.AppendFormat("\"Gender\": \"{0}\",", request.gender == "1" ? "男" : "女");
                body.AppendFormat("\"Age\": \"{0}\",", request.birth.Trim() == "" ? "1" : CommonBLL.GetAgeByBirthdate(Convert.ToDateTime(request.birth)));
                body.AppendFormat("\"Telephone\": \"{0}\",", request.tel);
                body.AppendFormat("\"Address\": \"{0}\",", request.addr);
                body.Append("\"PatientCode\": \"\",");
                body.Append("\"PatientCardCode\": \"\",");
                body.Append("\"AgeUnit\": \"岁\"");
                body.Append("},");
                body.AppendFormat("\"AppointmentSource\": \"{0}\"", request.source);
                body.Append("}");
                CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, "1：预约挂号接口请求body明文：\r\n" + CommonBLL.ConvertJsonString(body.ToString()));
                string postData_getorder = string.Format("{0},body:\"{1}", head.ToString(), HttpUtility.UrlEncode(Security.Base64.EncodeBase64(body.ToString())));
                postData_getorder += "\"}";
                url_getorder += postData_getorder;
                CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, "2：预约挂号接口请求密文：\r\n" + url_getorder);
                JObject obj_getorder = CommonBLL.HttpPost_CZHP(url_getorder);
                CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, "3：预约挂号接口返回明文：\r\n" + CommonBLL.ConvertJsonString(obj_getorder.ToString()));

                string code_getorder = obj_getorder["code"].ToString();

                if (string.Equals(code_getorder, "1"))
                {
                    var mJObj_getorder = JArray.Parse(obj_getorder["result"].ToString());
                    foreach (var dr in mJObj_getorder)
                    {
                        //判断医院订单号的长度，如果返回空值，则直接取消预约
                        string orderId = CommonBLL.GetOrderNo(dr["AppointmentOrder"]["OrderId"].ToString(), "11");
                        if (!string.IsNullOrEmpty(orderId))
                        {
                            //获取剩余可预约数
                            int count = 0;
                            WorkUpdateResponseModel workUpdateResponseModel = WorkBLL.GetWorkInfo(request.docid, request.wid, 9, out count);
                            Result.wid = request.wid.ToString();
                            Result.iid = dr["WorkDetail"]["Code"].ToString();
                            Result.inum = dr["WorkDetail"]["AppointmentOrder"].ToString();// request.inum;
                            Result.oid = dr["AppointmentOrder"]["OrderId"].ToString();
                            Result.price = (double.Parse(dr["AppointmentOrder"]["Amount"].ToString()) * 100).ToString();
                            Result.ofee = "0";
                            DateTime dt = Convert.ToDateTime(CommonBLL.RemoveStr(request.time));
                            Result.date = dt.ToString("yyyy-MM-dd");//---没有 用请求的就诊时间
                            Result.time = dt.ToString("HH:mm");
                            // + string.Format("({0})", dr["WorkDetail"]["AppointmentOrder"].ToString());//---没有 用请求的就诊时间

                            Result.count = count.ToString();//---没有 获取患者预约的排班对应的号源，计算出为预约的号源count
                            Result.dcount = count.ToString();//---没有 获取患者预约的排班对应的号源，计算出为预约的号源count
                            Result.tdate = dr["AppointmentOrder"]["OrderDate"].ToString();
                            Result.orderid = orderId;
                            ls_err = "";
                        }
                        else
                        {
                            CancelOrderResponseModel model = CancelOrderBLL.CancelOrder(request);
                            if (string.Equals(model.code, 1))
                            {
                                ls_err = "订单号超过约定的长度,系统自动取消该预约请求。";
                            }
                            else
                            {
                                ls_err = "订单号超过约定的长度,系统自动取消该预约请求时异常：" + model.msg;
                            }
                            return Result;
                        }
                    }
                }
                else
                {
                    ls_err = obj_getorder["msg"].ToString();
                    return Result;
                }
            }
            catch (Exception err)
            {
                ls_err = "预约失败:" + err.ToString();
                throw err;
            }
            CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, ls_err);
            return Result;
        }

        /// <summary>
        /// 长治和平预约【模拟调用模式】
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="ls_err">返回信息</param>
        /// <returns></returns>
        static OrderModel PreeOrder_CZHP_New(OrderParameterModel_Index request, ref string ls_err)
        {
            OrderModel Result = new OrderModel();
            try
            {
                //生成支付订单号
                string orderId = CommonBLL.GetOrderNo("11");
                if (!string.IsNullOrEmpty(orderId))
                {
                    //获取剩余可预约数
                    int count = 99;
                    int appstate = 0;
                    string resourceidNew = "";
                    string inumNew = "";
                    string timeNew = "";

                    DateTime dt = Convert.ToDateTime(CommonBLL.RemoveStr2(request.time));//请求的就诊时间
                    int days = CommonBLL.GetDays(DateTime.Now, dt) + 1;
                    //JObject obj_getorder = ChangZhiHePingBLL.GetOutPatientWorkSchedules(request.docid, days, request.wid, request.iid, out count, out appstate);
                    JObject obj_getorder = ChangZhiHePingBLL.GetOutPatientWorkSchedulesNew
                        (dt, request.docid, days, request.wid, request.iid, out count, out appstate,
                        out resourceidNew, out inumNew, out timeNew);
                    if (appstate == 2)
                    {
                        ls_err = "预约失败，号源已经预约。";
                        return Result;
                    }
                    else if (appstate == 3)
                    {
                        ls_err = "预约失败，排班已过期。";
                        return Result;
                    }
                    else if (appstate == 4)
                    {
                        ls_err = "预约失败，排班已停诊。";
                        return Result;
                    }
                    else if (appstate == -200 && count == -200)
                    {
                        ls_err = "预约异常，请联系技术人员。";
                        return Result;
                    }
                    else if (count <= 0 && resourceidNew == "")
                    {
                        ls_err = "预约失败，号已挂完。";
                        return Result;
                    }
                    else if (count > 0 && resourceidNew == "")
                    {
                        ls_err = "预约失败，该号源及以后的号源都已经预约，请重新选择时间。";
                        return Result;
                    }
                    // CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, "2：获取医生排班返回明文，未格式化：\r\n" + obj_getorder.ToString());

                    string code_getorder = obj_getorder["code"].ToString();
                    if (string.Equals(code_getorder, "1"))
                    {
                        //查不到排班 返回排班过期
                        var mJObj_getorder = JArray.Parse(obj_getorder["result"].ToString());
                        //CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, mJObj_getorder.ToString() + "----" + string.Equals(mJObj_getorder.ToString(), "[]"));
                        if (string.Equals(mJObj_getorder.ToString(), "[]"))
                        {
                            ls_err = "预约失败，排班已过期。";
                            return Result;
                        }
                        foreach (var dr in mJObj_getorder)
                        {
                            var mJObj_no = JArray.Parse(dr["WorkDetails"].ToString());
                            if (string.Equals(request.wid, dr["Code"].ToString()))
                            {
                                Result.wid = request.wid;
                                Result.iid = resourceidNew;
                                Result.inum = inumNew;
                                Result.oid = request.oid;
                                Result.date = dt.ToString("yyyy-MM-dd");//---没有 用请求的就诊时间
                                Result.time = timeNew;// string.Format("{0}({1})", timeNew, Result.inum);
                                Result.price = (double.Parse(dr["RegisterFee"].ToString()) * 100).ToString();//挂号费
                                Result.ofee = (double.Parse(dr["VisitFee"].ToString()) * 100).ToString(); //诊查费
                                Result.count = (count - 1).ToString();//---没有 获取患者预约的排班对应的号源，计算出为预约的号源count
                                Result.dcount = Result.count;//---没有 获取患者预约的排班对应的号源，计算出为预约的号源count
                                Result.tdate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                Result.orderid = orderId;
                                ls_err = "";

                                #region 构造实体
                                hars_appointmentrecord bll = new hars_appointmentrecord();
                                PreeRegisterModel.hars_appointmentrecord model = new PreeRegisterModel.hars_appointmentrecord();
                                model.state = 0;
                                model.addr = request.addr;
                                model.birth = request.birth;
                                model.card = request.card;
                                model.cid = request.cid;
                                model.cout = int.Parse(Result.count);
                                model.dcount = int.Parse(Result.dcount);
                                model.createdate = DateTime.Now;
                                model.ctype = int.Parse(request.ctype);
                                model.deptid = request.addr;
                                model.deptname = dr["Department"]["Name"].ToString();
                                model.doctorid = dr["Doctor"]["DoctorCode"].ToString();
                                model.doctorname = dr["Doctor"]["Name"].ToString();
                                model.doctorrank = dr["Doctor"]["Rank"].ToString();//注意：rank 可能为空
                                int gender = -2;
                                int.TryParse(request.gender, out gender);
                                model.gender = gender;
                                model.iid = Result.iid;
                                model.inum = Result.inum;
                                model.isdelete = 0;
                                int mtype = 0;
                                int.TryParse(request.mtype, out mtype);
                                model.lastdate = DateTime.Now;
                                model.mtype = mtype;
                                model.name = request.name;
                                model.ofee = int.Parse((double.Parse(dr["RegisterFee"].ToString()) * 100).ToString());
                                model.price = int.Parse((double.Parse(dr["VisitFee"].ToString()) * 100).ToString());
                                model.price2 = int.Parse((double.Parse(dr["AddtionalFee"].ToString()) * 100).ToString());
                                model.oid = request.oid;
                                model.orderid = orderId;
                                int ptype = 0;
                                int.TryParse(request.ptype, out ptype);
                                model.ptype = ptype;
                                int rtype = -2;
                                int.TryParse(request.rtype, out rtype);
                                model.rtype = rtype;
                                model.tdate = dt.ToString("yyyy-MM-dd hh:mm:ss");//就诊时间
                                model.tel = request.tel;
                                model.wid = request.wid;
                                if (bll.Add(model))
                                {
                                    return Result;
                                }
                                else
                                {
                                    ls_err = "预约失败，错误代码：002";
                                }
                                #endregion
                            }
                        }
                    }
                    else
                    {
                        ls_err = "预约的排班信息不存在。";
                    }
                }
                else
                {
                    ls_err = "订单号生成异常，错误代码：001";
                    return Result;
                }
            }
            catch (Exception err)
            {
                ls_err = "预约失败:" + err.ToString();
                throw err;
            }
            CommonBLL.WriteFile_New(CommonBLL.bizCode_getorder, ls_err);
            return Result;
        }

        /// <summary>
        /// 反序列化请求字符串
        /// </summary>
        /// <param name="head_json"></param>
        /// <param name="body_json"></param>
        /// <returns></returns>
        public static OrderRequestModel ReturnOrderRequestModel(string head_json, string body_json)
        {
            try
            {
                Head head = csSerialize.RequestHeadInfo(head_json);

                OrderParameterModel body = csSerialize.OrderRequestBodyInfo(body_json);

                OrderRequestModel orderRequestModel = new OrderRequestModel();
                orderRequestModel.head = head;
                orderRequestModel.body = body;
                return orderRequestModel;
            }
            catch (Exception err)
            {

                throw;
            }
        }

        /// <summary>
        /// 预约保存验证患者信息
        /// 增加returnvalue返回值  liujia151201
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="strRef"></param>
        static void VerifyControlSave(OrderParameterModel_Index request, ref string strRef, ref int ReturnValue)
        {
            if (request.wid.Trim() == "")
                throw new Exception("排班标识不能为空！");
            if (VariableBLL.bPreTime)
            {
                if (request.iid.Trim() == "")
                    throw new Exception("号源标识不能为空！");
                if (request.inum.Trim() == "")
                    throw new Exception("号源序号不能为空！");
                if (Common.ToInt(request.iid) <= 0)
                    throw new Exception("号源标识非法！");
                if (Common.ToInt(request.inum) <= 0)
                    throw new Exception("预约序号非法！");
            }

            if (!VariableBLL.bPreTime)
            {
                DataSet dsNum = OrderDAL.SelectNum(request.wid.Trim());
                if (dsNum.Tables[0].Rows.Count == 0)
                {
                    throw new Exception("排班标识有误，无法查询到预约信息！");
                }
                DataRow drNum = dsNum.Tables[0].Rows[0];
                request.inum = drNum["iNum"].ToString();//序号预约指定序号和时间 lhl20131214
                request.time = drNum["dStartTime"].ToString();
            }
            DateTime dtStart = Common.ToDateTime(request.time.Trim());
            if (dtStart < Common.ToDateTime("1900-01-01 1:00:00"))
            {
                throw new Exception("就诊时间为空或非法！");
            }
            DateTime dtNow = Common.GetSysTime();
            if (VariableBLL.bPreTime)
            {
                //if (dtStart > Common.ToDateTime(dtStart.ToShortDateString() + " 12:00:00") && dtStart < Common.ToDateTime(dtStart.ToShortDateString() + " 14:00:00"))
                //    throw new Exception("就诊时间不可以为午休时间！");//预约添加时间限制，必须为上班时间 lhl20140719
                //if (dtStart > Common.ToDateTime(dtStart.ToShortDateString() + " 18:00:00") || dtStart < Common.ToDateTime(dtStart.ToShortDateString() + " 07:00:00"))
                //    throw new Exception("就诊时间不可以为下班时间！");
            }
            if (Common.ToHex(request.name.Trim(), "gb2312").Length > 15 || Common.ToHex(request.name.Trim(), "gb2312").Length < 4)
                throw new Exception("患者姓名非法！");
            DateTime dBirthday = Common.ToDateTime(request.birth.Trim());
            if (dBirthday < Common.ToDateTime("1900-01-01 1:00:00") || dBirthday > DateTime.Now)//预约挂号添加生日是否大于当前时间验证 lhl20140410
            {
                throw new Exception("出生日期为空或非法！");
            }
            if (request.tel.Trim().Length < 7 || request.tel.Trim().Length > 12)
            {
                throw new Exception("联系电话格式有误！");
            }
            if (Common.ToInt(request.gender.Trim()) <= 0)
            {
                throw new Exception("性别不能为空！");
            }
            if (request.card.Trim() != "")
            {
                if (request.card.Trim().Length < 15 || request.card.Trim().Length > 18)
                {
                    throw new Exception("身份证号格式有误！");
                }
            }
            if (Common.ToInt(request.wid) <= 0)
                throw new Exception("排班标识非法！");

            if (Common.ToInt(request.ptype) <= 0)
                throw new Exception("患者类型非法！");
            if (request.rtype.Trim().Length >= 20)
                throw new Exception("复诊类型非法！");
            int iout = 0;
            if (!int.TryParse(request.atype, out iout))
                throw new Exception("预约方式参数不能为空！");
            if (Common.ToInt(request.atype) != Common.ToBit(VariableBLL.bPreTime))
                throw new Exception("预约方式有误！");
            //if (request.body.iWorkPlanTypeID != null)
            //    VariableBLL.iWorkPlanTypeID = Common.ToInt(request.body.iWorkPlanTypeID);
            //else
            VariableBLL.iWorkPlanTypeID = 11;
            if (dtStart.AddDays(-VariableBLL.iYYDaySpan).ToShortDateString() == dtNow.ToShortDateString())//院外预约添加预约时间验证，是否在规定时间开始预约 lhl20140422
            {
                DataView dvType = CommonBLL.GetDataView("OPDWorkPlanType");
                dvType.RowFilter = "iWorkPlanTypeID=" + VariableBLL.iWorkPlanTypeID;
                if (dvType.Count > 0)
                {
                    DateTime dtYYStart = Common.ToDateTime(dtNow.ToShortDateString() + " " + dvType[0]["nStartTime"]);
                    if (dtYYStart > dtNow)
                    {
                        throw new Exception(dtNow.ToShortDateString() + "的号在" + dvType[0]["nStartTime"] + "点后方可预约！");
                    }
                }
            }
            int iInBlackCount = 0;
            int bFreePree = 1;
            //增加同煤版本过程名判断  liujia150812
            string ProcedureName = "sp_VerifyPatientInfo";
            if (VariableBLL.IFTmkyy)
            {
                if (request.preeflag == "1")
                {
                    ProcedureName = "sp_VerifyPatientInfo_Tmkyy";
                }
                else
                {
                    ProcedureName = "sp_NowDay_VerifyPatientInfo_Tmkyy";
                }
            }  //非同煤版都走sp_VerifyPatientInfo过程，无论预约还是当日   liujia151206
            //增加返回值  liujia151201
            ReturnValue = OrderDAL.VerifyPatientInfo(ProcedureName, request.name.Trim(), Common.ToInt(request.gender.Trim()), dBirthday, ref iInBlackCount,
                "", request.card.Trim(), Common.ToInt(request.wid.Trim()), request.tel.Trim(), dtStart, bFreePree, ref strRef);

            //增加判断，校验失败不提示爽约次数  liujia151221
            if (bFreePree == 1 && iInBlackCount > 0 && ReturnValue == 1)
            {
                strRef = "该患者已有" + iInBlackCount + "次爽约，再有" + (VariableBLL.iBlackPreeCount - iInBlackCount) + "次，则不能预约挂号！";
            }

        }

        /// <summary>
        /// 判断是预约挂号还是当日挂号   liujia151201
        /// </summary>
        /// <param name="iWorkPlanid"></param>
        /// <returns></returns>
        private static bool IFPreeRegister(int iWorkPlanid)
        {
            try
            {
                DataSet ds = OrderDAL.IFPreeRegister(iWorkPlanid);
                if (ds == null || ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
                {
                    return false;
                }
                DateTime dStartTime = Common.ToDateTime(ds.Tables[0].Rows[0]["dStartTime"]);
                DateTime dEndTime = Common.ToDateTime(ds.Tables[0].Rows[0]["dEndTime"]);
                DateTime dtNow = CommonBLL.GetSystemTime();
                if (dStartTime < dtNow && dEndTime > dtNow)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception err)
            {

                throw;
            }
        }
    }
}
